package com.paic.custserv.authentication;

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserCache;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.core.userdetails.cache.NullUserCache;

import com.paic.custserv.common.Constant;
import com.paic.custserv.domain.AppUser;
import com.paic.custserv.utils.CommonUtil;
import com.paic.custserv.vo.SysMenuVO;


public class DefaultAuthenticationProvider extends DaoAuthenticationProvider {
	
	private Logger LOG = Logger.getLogger(DefaultAuthenticationProvider.class);
	
	private UserCache userCache = new NullUserCache();
	
	private boolean forcePrincipalAsString = false;
	
	/**
     * 权限.
     * 
     * @param authentication 权限对象
     * @return Authentication
     */
    public Authentication authenticate(Authentication authentication) {
        String userAccount = authentication.getName();

        boolean cacheWasUsed = true;
        UserDetails user = this.userCache.getUserFromCache(userAccount);

        if (user == null) {
            cacheWasUsed = false;
            try {
                user = retrieveUser(userAccount, (UsernamePasswordAuthenticationToken)authentication);
            }
            catch (UsernameNotFoundException notFound) {
                LOG.debug("User '" + userAccount + "' not found");
                if (hideUserNotFoundExceptions) {
                    throw new AuthenticationException(AuthConstant.USER_NOT_FOUND_MESSAGE);
                } else {
                    throw notFound;
                }
            }
        }

        AppUser appUser = (AppUser)user;
        // 如果一个用户配置的角色，没有勾选任何子权限，或者该用户没有配置任何角色，该用户在登录时应该提示：此用户没有任何权限，请联系管理员
        List<SysMenuVO> list = appUser.getSysMenuList();
        if(CommonUtil.isNullOrEmpty(list)) {
        	throw new AuthenticationException(AuthConstant.NO_AUTHORITY_MESSAGE);
        }

        try {
            additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken)authentication);
        }
        catch (AuthenticationException exception) {
            if (cacheWasUsed) {
                // There was a problem, so try again after checking
                // we're using latest data (i.e. not from the cache)
                cacheWasUsed = false;
            }
            else {
                throw exception;
            }
        }

        if (!cacheWasUsed) {
            this.userCache.putUserInCache(user);
        }
        Object principalToReturn = user;
        if (forcePrincipalAsString) {
            principalToReturn = user.getUsername();
        }

        return createSuccessAuthentication(principalToReturn, authentication, user);
    }

}
